import json
import time
from datetime import datetime
from urllib.parse import urlencode

import constants
from logger import logger
from models import TaskVideo
from service.task_site_service import TaskSiteService
from service.task_video_service import TaskVideoService
from task import download_file
from util import crypto_utils, string_utils, md5_util
from util.requests_utils import RequestUtils


def get_remote_data(url=None, method="get", params=None, headers=None):
    if method == 'get':
        if params.get("get"):
            param_url = "?" + urlencode(params.get("get"))
            url = f"{url}{param_url}"
        return RequestUtils.get(url, headers=headers)
    elif method == 'post':
        if params.get("get"):
            param_url = "?" + urlencode(params.get("get"))
            url = f"{url}{param_url}"
        post_params = None
        if params.get("post"):
            post_params = params.get("post")
        return RequestUtils.post(url, post_params, headers=headers)


# video_service = TaskVideoService()
# site_service = TaskSiteService()

def create_task_video(video_data, site):
    title_str = string_utils.truncate_string(string_utils.filter_string(video_data.get("title")))
    title_en_str = string_utils.truncate_string(string_utils.filter_string(video_data.get("title_en")))
    id = md5_util.MD5Util.encrypt_string(video_data.get("id") + title_str)
    return TaskVideo(
        id=id,
        v_id = video_data.get("id"),
        type_name=site.get("type_name"),
        site_name=site.get("site_name"),
        title=title_str,
        title_en=title_en_str,
        image_url=video_data.get("thumbNails"),
        video_url="/sevenVideos/" + str(video_data.get("vId")),
        video_path=site.get("site_url") + "/sevenVideos/" + str(video_data.get("vId")),
        site_url=site.get("site_url"),
        author=video_data.get("user"),
        play_num=video_data.get("views"),
        duration=video_data.get("duration"),
        duration_str=video_data.get("durationStr"),
    )


def fetch_and_process_videos(site, ids, paginate=True):
    video_service = TaskVideoService()
    url = site.get("list_link")
    method = site.get("method")
    params = json.loads(site.get("param"))
    headers = {
        "origin": site.get("origin"),
        "User-Agent": constants.BROWER_VERSION,
    }

    video_list = []
    page = 1

    try:
        while True:
            if not params["get"]["page"]:
                params["get"]["page"] = page
            r = get_remote_data(url, method, params, headers)
            if not r or page > constants.MAX_FETCH_PAGE:
                break

            aes_result = json.loads(r.text).get("r")
            result_list_str = crypto_utils.decrypt(aes_result, constants.VIDEO_KEY)
            result_list = json.loads(result_list_str)

            for video_data in result_list:
                task_video = create_task_video(video_data, site)
                if task_video.id not in ids:
                    # 采集其它详情数据
                    get_video_detail(task_video, site)
                    video_list.append(task_video)
                    ids.append(task_video.id)

            if len(video_list) > 200:
                video_service.create_task_videos(video_list)
                video_list = []

            if not paginate or not result_list:  # 如果不分页或结果为空，则停止循环
                break

            page += 1
        video_service.create_task_videos(video_list)
    except Exception as e:
        logger.error(e)


def fetch_videos(category=None, fetch_all=False):
    """
    采集视频列表的统一方法

    Args:
        category: 分类ID，用于过滤站点
        fetch_all: 是否采集所有视频（分页），False表示只采集最新视频（不分页）
    """
    try:
        video_service = TaskVideoService()
        site_service = TaskSiteService()

        # 根据fetch_all参数确定日志信息和分页参数
        if fetch_all:
            logger.info("采集所有视频任务启动....")
            paginate = True
            log_prefix = "采集所有"
        else:
            logger.info("采集最新视频任务启动....")
            paginate = False
            log_prefix = "采集最新"

        start_time = time.time()  # 获取当前的时间作为开始时间

        # 根据传入的category过滤站点列表
        site_list = site_service.get_all_task_sites()
        if category:
            try:
                category_id = int(category)
                site_list = [site for site in site_list if site.get("id") == category_id]
            except (ValueError, TypeError):
                site_list = []  # 如果转换失败，返回空列表

        ids = video_service.get_all_ids()
        for site in site_list:
            if site.get("site_name") == '91':
                site_start_time = time.time()  # 获取当前的时间作为开始时间
                fetch_and_process_videos(site, ids, paginate=paginate)
                site_end_time = time.time()  # 获取当前的时间作为结束时间
                site_execution_time = site_end_time - site_start_time  # 计算差值得到执行时间
                logger.info(f"采集{site.get('site_name')}的{site.get('type_name')}最新视频任务结束,执行时长：{site_execution_time} 秒")
                site_service.update_site_execute_time(site.get("id"))
        end_time = time.time()  # 获取当前的时间作为结束时间
        execution_time = end_time - start_time  # 计算差值得到执行时间
        logger.info(f"{log_prefix}视频任务结束,执行时长：{execution_time} 秒")
        download_file.download_all_file()
    except Exception as e:
        # 处理异常
        error_msg = "采集全量" if fetch_all else "采集最新"
        logger.error(f"{error_msg}视频列表报错，: {e}")

# 为了保持向后兼容，可以保留原有的方法名作为包装函数
def get_all_video_list(category=None):
    """采集所有视频列表（保持向后兼容）"""
    return fetch_videos(category=category, fetch_all=True)

def get_new_video_list(category=None):
    """采集最新视频列表（保持向后兼容）"""
    return fetch_videos(category=category, fetch_all=False)


def get_video_detail(video, site):
    try:
        url = video.site_url + video.video_url
        method = "post"
        params = {
            "post": {
                "userId": "66c5aa5ac9612828c8da4478",
                "url_search": "",
                "token": "ufd",
                "ip": "127.0.0.1",
                "deviceInfo": {},
                "app": "91porn.porn"
            }
        }
        headers = {
            "origin": site.get("origin"),
            "User-Agent": constants.BROWER_VERSION,
            "Authorization": constants.VIDEO_Authorization,
        }
        r = get_remote_data(url, method, params, headers)
        if r:
            aes_result = json.loads(r.text).get("r")
            result_str = crypto_utils.decrypt(aes_result, constants.VIDEO_KEY)
            result = json.loads(result_str)
            video.size = result.get("size")
            video.video_path = result.get("m3u8s")[0]
            video.release_time = result.get("time") if result.get("time") else datetime.now().strftime('%Y-%m-%d')

            return video
    except Exception as e:
        # 处理异常
        print("采集视频详情报错：" + str(e))


if __name__ == '__main__':
    get_new_video_list()
